package org.agile4j.algorithm.linkedlist;

class Link {	// 此为链表工具类，保存多个对象
	// Node类负责数据的节点排列，此功能只应该为Link类使用
	private class Node {	// 私有内部类保证外部不可用
		private Object data ;	// 保存的类型暂时为String
		private Node next ;	// 下一个节点
		public Node(Object data){
			this.data = data ;	// 节点要有数据
		}
		// 第一次（Link）：this = Link.root；
		// 第二次（Node）：this = Link.root.next；
		// 第三次（Node）：this = Link.root.next.next；
		public void addNode(Node newNode) {
			if (this.next == null) {	// 当前节点之后有空余
				this.next = newNode ;	// 保存新节点
			} else {	// 当前节点之后有数据
				this.next.addNode(newNode) ;
			}
		}
		public Object getNode(int index) {
			// 查找索引号与当前索引号相同，则返回
			// 此时要考虑不同的情况，不同的情况，索引号一定改变
			if (Link.this.foot ++ == index) {
				return this.data ;	// 当前节点数据
			} else {	// 数据索引一定存在
				return this.next.getNode(index) ;
			}
		}
		public boolean containsNode(Object data) {
			if (data.equals(this.data)) {	// 当前节点数据符合
				return true ;
			} else {
				if (this.next != null) {	// 还有下一个节点
					return this.next.containsNode(data) ;
				} else {	// 如果没有下一个节点
					return false ;
				}
			}
		}
		// 第一次（Link）：this = root.next、previous = root；
		// 第二次（Node）：this = root.next.next、previous = root.next
		public void removeNode(Node previous,Object data) {
			if (data.equals(this.data)) {	// 此处为要删除节点
				previous.next = this.next ;	// 当前节点取消了
			} else {	// 继续向后判断
				this.next.removeNode(this,data) ;
			}
		}
		public void toArrayNode(){
			Link.this.retData[Link.this.foot ++] = this.data ;
			if (this.next != null) {
				this.next.toArrayNode() ;
			}
		}
	}
	// ++++++++++++++++++++++++++++++++++++++
	private int foot ; // 保存操作的索引号
	private int count ;	// 保存元素个数
	private Node root ;	// 根节点
	private Object retData [] ;	// 返回的数组
	public void add(Object data) {
		if (data == null) {
			return ;	// 直接返回给调用处
		}
		Node newNode = new Node(data) ;	// 新节点
		if (this.root == null) {	// 没有根节点
			this.root = newNode ;	// 保存新节点
		} else {
			this.root.addNode(newNode) ;
		}
		this.count ++ ;
	}
	public int size() {
		return this.count ;
	}
	public boolean isEmpty() {
		return this.count == 0 ;
	}
	public Object get(int index) {
		if (index < this.count) {	// 在范围内
			this.foot = 0 ;	// 重置
			return this.root.getNode(index) ;
		}
		return null ;	// 不在范围内
	}
	public boolean contains(Object data) {
		if (this.count == 0 || data == null) {
			return false ;
		}
		return this.root.containsNode(data) ;
	}
	public void remove(Object data) {	// 删除数据
		if (this.contains(data)) {	// 数据存在
			// 要删除数据与根节点相同
			if (data.equals(this.root.data)) {
				this.root = this.root.next ;	// 修改根节点
			} else {	// 删除的不是根节点
				this.root.next.removeNode(this.root,data) ;
			}
			this.count -- ;
		}
	}
	public void clean() {
		this.root = null ;
		this.count = 0 ;
	}
	public Object [] toArray() {
		if (this.root == null) {
			return null ;
		}
		this.retData = new Object [this.count] ;
		this.foot = 0 ;	// 清零
		this.root.toArrayNode() ;	// 交给Node类处理
		return this.retData ;
	}
}
@SuppressWarnings("ALL")
public class LinkDemo {
	public static void main(String args[]) {
		Link all = new Link() ;
		all.add("Hello") ;	// 向上转型
		all.add("World") ;	// 向上转型
		all.add("NIHAO") ;	// 向上转型
		all.remove("NIHAO") ;
		Object ret [] = all.toArray() ;
		for (int x = 0 ; x < ret.length ; x ++) {
			String str = (String) ret[x] ;
			System.out.println(str) ;
		}
	}
}